package org.seed.rpc.core.routing;

import org.seed.rpc.core.RuntimeLocal;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class RoundRobinStrategy implements RoutingStrategy {

    private static AtomicInteger index = new AtomicInteger(0);
    private static int preOptionalSize = 0;

    @Override
    public Endpoint determineEndpoint(String serviceName) {
        List<String> endpoints = RuntimeLocal.getEndpointList(serviceName);
        if (endpoints == null || endpoints.size() == 0) {
            return null;
        }
        int size = endpoints.size();
        int useIndex;
        if (size == preOptionalSize) {
            useIndex = index.getAndAdd(1);
        } else {
            preOptionalSize = size;
            useIndex = (int) Math.random() * size;
        }
        useIndex = useIndex % size;
        String endpointStr = endpoints.get(useIndex);
        return new Endpoint(endpointStr);
    }

    @Override
    public Endpoint determineEndpointExcept(String serviceName, List<String> excepts) {
        List<String> endpoints = RuntimeLocal.getEndpointList(serviceName);
        if (endpoints == null || endpoints.size() == 0) {
            return null;
        }
        Iterator<String> iterator = endpoints.iterator();
        while (iterator.hasNext()){
            if(excepts.contains(iterator.next())){
                iterator.remove();
            }
        }
        if(endpoints.size()==0){
            return null;
        }
        int size = endpoints.size();
        int useIndex;
        if (size == preOptionalSize) {
            useIndex = index.getAndAdd(1);
        } else {
            preOptionalSize = size;
            useIndex = (int) Math.random() * size;
        }
        useIndex = useIndex % size;
        String endpointStr = endpoints.get(useIndex);
        return new Endpoint(endpointStr);
    }
}
